
/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 abstract_bitmap.h

	$Header: /game/abstract_bitmap.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "abstract_bitmap.h"

#include "alpha_blend.h"
#include "pixel_24.h"
// ----------------------------------------------------------------------
// fill an 8 bit bitmap with a value.
// ----------------------------------------------------------------------
void fill( t_abstract_bitmap8& bitmap, t_screen_rect const& rect, t_uint8 pixel )
{
	t_uint8* ptr = bitmap.advance_line( bitmap.get_data_ptr(), rect.top ) + rect.left;
	int      height = rect.height();
	int      width  = rect.width();

	while (height--)
	{
		memset( ptr, pixel, width );
		ptr = bitmap.advance_line( ptr );
	}
}


// ----------------------------------------------------------------------
// fill a 16 bit bitmap with a value.
// ----------------------------------------------------------------------
void fill( t_abstract_bitmap16& bitmap, t_screen_rect const& rect, t_uint16 pixel )
{
	t_uint16* ptr = bitmap.advance_line( bitmap.get_data_ptr(), rect.top ) + rect.left;
	int       height = rect.height();
	int       width  = rect.width();
	int       increment = bitmap.get_pitch() - width * sizeof(t_uint16);
	int       i;

	while (height--)
	{
		i = width;
		while (i--)
			*ptr++ = pixel;
		ptr = bitmap.byte_increment( ptr, increment );
	}
}

// ----------------------------------------------------------------------
// fill a 24 bit bitmap with a value.
// ----------------------------------------------------------------------
void fill( t_abstract_bitmap24& bitmap, t_screen_rect const& rect, t_pixel_24 pixel )
{
	t_pixel_24* ptr = bitmap.advance_line( bitmap.get_data_ptr(), rect.top ) + rect.left;
	int         height = rect.height();
	int         width  = rect.width();
	int         increment = bitmap.get_pitch() - width * sizeof(t_pixel_24);
	int         i;

	while (height--)
	{
		i = width;
		while (i--)
			*ptr++ = pixel;
		ptr = bitmap.byte_increment( ptr, increment );
	}
}

// ----------------------------------------------------------------------
// fill a 32 bit bitmap with a value.
// ----------------------------------------------------------------------
void fill( t_abstract_bitmap32& bitmap, t_screen_rect const& rect, t_pixel_32 pixel )
{
	t_pixel_32* ptr = bitmap.advance_line( bitmap.get_data_ptr(), rect.top ) + rect.left;
	int         height = rect.height();
	int         width  = rect.width();
	int         increment = bitmap.get_pitch() - width * sizeof(t_pixel_32);
	int         i;

	while (height--)
	{
		i = width;
		while (i--)
			*ptr++ = pixel;
		ptr = bitmap.byte_increment( ptr, increment );
	}
}

// ----------------------------------------------------------------------
// blend a 16 bit bitmap with a value.
// ----------------------------------------------------------------------
void fill( t_abstract_bitmap16& bitmap, t_screen_rect const& rect, t_uint16 pixel, int alpha )
{
	t_uint16* ptr = bitmap.advance_line( bitmap.get_data_ptr(), rect.top ) + rect.left;
	int       height = rect.height();
	int       width  = rect.width();
	int       increment = bitmap.get_pitch() - width * sizeof(t_uint16);
	int       i;

	while (height--)
	{
		i = width;
		while (i--)
		{
			*ptr = alpha_blend16( *ptr, pixel, alpha );
			ptr++;
		}
		ptr = bitmap.byte_increment( ptr, increment );
	}
}


// ----------------------------------------------------------------------
// draw from one 16 bit bitmap to another.  Assumes identical bit packing.
// ----------------------------------------------------------------------
void draw( t_abstract_bitmap16& dest, t_screen_point const& point,
		   t_abstract_bitmap16 const& source, t_screen_rect const& source_rect )
{
	t_screen_point dest_offset = point - source_rect.top_left();
	t_screen_rect  dest_rect   = source_rect + dest_offset;
	t_screen_point source_point;

	dest_rect = intersection( dest_rect, dest.get_rect() );
	source_point = dest_rect.top_left() - dest_offset;

	int width  = dest_rect.width();
	int height = dest_rect.height();

	if (height <= 0 || width <= 0)
		return;

	int copy_size = width * sizeof(t_uint16);

	t_uint16 const* source_ptr = source.advance_line( source.get_data_ptr(), source_point.y )
		                         + source_point.x;
	t_uint16* dest_ptr = dest.advance_line( dest.get_data_ptr(), dest_rect.top ) + dest_rect.left;

	while (height--)
	{
		memcpy( dest_ptr, source_ptr, copy_size );
		source_ptr = source.advance_line( source_ptr );
		dest_ptr   = dest.advance_line( dest_ptr );
	}
}
